package com.plugin.sproutcore.ui.wizards;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

import com.plugin.sproutcore.core.validator.IValidate;
import com.plugin.sproutcore.ui.events.ChangeProjectEvent;
import com.plugin.sproutcore.ui.events.ChangeProjectListener;
import com.plugin.sproutcore.ui.events.ChangeSelectionEvent;
import com.plugin.sproutcore.ui.events.ChangeSelectionListener;
import com.plugin.sproutcore.ui.widgets.ProjectSelector;
import com.plugin.sproutcore.util.ProjectUtil;
import com.plugin.sproutcore.util.SWTUtil;
import com.plugin.sproutcore.util.StringUtil;

public class NewModelWizardPage extends WizardPage implements IValidate
{
	private ProjectSelector projectBrowser;
	private Text className;
	private Text previewText;
	
	public NewModelWizardPage(ISelection selection) 
	{
		super("wizardPage");
		projectBrowser = new ProjectSelector(this, selection);
		setTitle("New SproutCore Model");
		setDescription("This wizard creates a new SproutCore model for a targeted app");
	}

	public void createControl(Composite parent) 
	{
		final Composite container = new Composite(parent, SWT.NULL);
		final GridLayout layout = new GridLayout(2, false);
		container.setLayout(layout);
		try 
		{	
			projectBrowser.getLayout().marginBottom = 10;
			projectBrowser.createControl(container, layout.numColumns);
			projectBrowser.addChangeProjectListener(new ChangeProjectListener() 
			{
				@Override
				public void projectChanged(ChangeProjectEvent event) {
					refresh();
				}
			});
			projectBrowser.addChangeSelectionListener(new ChangeSelectionListener() 
			{
				@Override
				public void selectionChanged(ChangeSelectionEvent event) {
					refresh();
				}
			});
			
			SWTUtil.createSeparator(container, layout.numColumns);
			
			Label label = new Label(container, SWT.NONE);
			label.setText("ClassName:");
			
			className = new Text(container, SWT.BORDER);
			className.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			className.setText("ModelName");
			className.addModifyListener(new ModifyListener() 
			{
				public void modifyText(ModifyEvent e) {
					refresh();
				}
			});
			
			createPreviewControls(container);
			
			refresh();
		} 
		catch (CoreException e) 
		{
			// show error
			e.printStackTrace();
		}
		setControl(container);
	}
	
	private void createPreviewControls(Composite parent)
	{
		final GridData layoutData = new GridData(GridData.FILL_HORIZONTAL);
		new Label(parent, SWT.NONE);
		previewText = new Text(parent, SWT.READ_ONLY);
		previewText.setLayoutData(layoutData);
	}
	
	public void setVisible(boolean visible) 
	{
		super.setVisible(visible);
		if (visible) {
			if (className != null && className.isEnabled()) {
				className.setFocus();
			}
		}
	}
	
	private final void refresh() 
	{
		List<IStatus> errors = new ArrayList<IStatus>();
		validate(errors);
		
		if (errors.size() == 0)
		{
			StringBuilder builder = new StringBuilder();
			builder.append(getFullClassName());
			previewText.setText(builder.toString());
			
			setPageComplete(true);
			setErrorMessage(null);
		}
		else
		{
			setPageComplete(false);
			setErrorMessage(errors.get(0).getMessage());
		}
	}
		
	public final void validate(List<IStatus> errors)
	{
		StringTokenizer st = new StringTokenizer(className.getText());
		if (st.countTokens() > 1) {
			IStatus status = ProjectUtil.createErrorStatus("ClassName is not valid. Classname's can not have spaces");
			errors.add(status);
		}
		projectBrowser.validate(errors);
	}
	
	public String getFullClassName()
	{
		StringBuilder builder = new StringBuilder();
		builder.append(StringUtil.capFirstLetter(getAppName()));
		builder.append('.');
		builder.append(StringUtil.capFirstLetter(getClassName()));
		builder.trimToSize();
		return builder.toString();
	}
	
	public String getAppName()
	{
		return projectBrowser.getAppName();
	}
	public String getClassName()
	{
		return className.getText().trim();
	}
}
